package com.wzl.kgmusic

import android.media.MediaCodec
import android.media.MediaFormat
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.ByteBuffer

class ConvertPcmToMp3 {
    fun convertPcmToMp3(pcmFilePath: String, mp3FilePath: String) {
        val pcmFile = File(pcmFilePath)
        val mp3File = File(mp3FilePath)

        // 创建 MediaCodec 编码器
        val mediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_MPEG)

        // 配置 MediaCodec 编码器
        val mediaFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_MPEG, 44100, 2)
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 128000)
        mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
        mediaCodec.start()

        // 读取 PCM 文件数据并编码为 MP3
        val buffer = ByteArray(1024 * 4)
        val inputStream = BufferedInputStream(FileInputStream(pcmFile))
        val outputStream = BufferedOutputStream(FileOutputStream(mp3File))

        var inputBufferIndex: Int
        var outputBufferIndex: Int
        var outputBuffer: ByteBuffer

        while (true) {
            inputBufferIndex = mediaCodec.dequeueInputBuffer(10000)
            if (inputBufferIndex >= 0) {
                val inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex)!!
                val readBytes = inputStream.read(buffer)
                if (readBytes < 0) {
                    mediaCodec.queueInputBuffer(
                        inputBufferIndex,
                        0,
                        0,
                        0L,
                        MediaCodec.BUFFER_FLAG_END_OF_STREAM
                    )
                    break
                } else {
                    inputBuffer.put(buffer, 0, readBytes)
                    mediaCodec.queueInputBuffer(
                        inputBufferIndex,
                        0,
                        readBytes,
                        System.nanoTime() / 1000,
                        0
                    )
                }
            }

            outputBufferIndex = mediaCodec.dequeueOutputBuffer(MediaCodec.BufferInfo(), 10000)
            if (outputBufferIndex >= 0) {
                outputBuffer = mediaCodec.getOutputBuffer(outputBufferIndex)!!
                val info = MediaCodec.BufferInfo()
                mediaCodec.getOutputFormat(outputBufferIndex)
                outputStream.write(outputBuffer.array(), 0, info.size)
                mediaCodec.releaseOutputBuffer(outputBufferIndex, false)
            } else {
                break
            }
        }

        inputStream.close()
        outputStream.flush()
        outputStream.close()
        mediaCodec.stop()
        mediaCodec.release()
    }
}
